前言
本文主要是在读《JavaScript高级程序语言设计》一书有关正则表达式的章节的知识点记录,方便后续查阅。
什么是正则表达式
正则表达式是用来描述字符组合的某种规则。它可以帮助验证字符串是否满足某种字符组合规则或者通过某个规则查找对应的字符序列。
举个例子:比如我想验证一个输入框中输入的是否是手机号码,那么我们需要为这个输入框定义一个输入规则,比如11位字符、每个字符都必须是0-9、以及更细节的信息像第一位不能是0等规则。此时我们就可以定义一个正则表达式,将所有的规则通过正则表达出来,去验证输入框的内容是否满足正则表达式定义的规则。
JavaScript中定义正则表达式对象
JavaScript中的正则表达式对象有两种定义方式:正则表达式直接量
和RegExp()构造函数
。定义代码如下:
//定义JavaScript正则对象的两种方式
var pattern = /s$/;
var pattern = new RegExp("s$");
直接量字符
正则表达式中所有字母和数字都是按字面含义进行匹配的,例如'a'就可以匹配到'a'字符。
JavaScript也支持非字母的字符匹配。正则表达式通过””+字母的形式将字母原先的含义进行了转义来表示其他特殊的字符。例如\n匹配换行符。
正则表达式中很多符号具有特殊含义:^ $ . * + ? = ! : | / () [] {}。如果想要匹配这些字符需要使用"\"进行转义。
字符类
现在我们知道我们可以用a去匹配a字符,b去匹配b字符。那么如果我需要匹配所有的小写字母该怎么做?
正则表达式使用[]来构造一个字符类。一个字符类可以匹配它所包含的任意一个字符。例如/[abc]/就能够匹配字母”a”、”b”或”c”中的任意一个。另外在字符类中使用^可以进行否定操作,例如'/[^abc]/'表示匹配”a”、”b”或”c”以外的任意一个字符。
字符类还可以使用连字符表示字符范围,例如/[a-z]/匹配所有小写字母。由于某些字符类非常常用,所以正则规范了一些特殊字符表示一个特定的字符类,例如/\w/等价于[a-zA-Z0-9]。
重复
现在我们有有了新的需求,就是想要某个字符类匹配多次,例如匹配5-7个数字,可以使用/\d{5,7}/进行匹配,由于某些重复种类非常常用,所以正则规范了特殊符号来表示,例如”+”表示匹配1次或多次,等价于{1,}等。
非贪婪的重复
使用重复进行匹配时会尽可能多的进行匹配,我们称之为贪婪匹配。例如/a+/可以匹配一个或多个连续的字母a,当使用”aaa”作为匹配字符串时,正则表达式会匹配连续的三个a。
非贪婪匹配只需在待匹配字符后跟随一个?,例如:”??”、”+?”、”*?”或”{1,5}?”。例如/a+?/也可以匹配一个或多个连续的字母a,但是它会尽可能少的匹配。
选择、分组和引用
选择
选择:字符”|”用于分隔可选择的字符,例如/d{3}|[a-z]{4}/可以匹配三位数字或者四个小写字母。选择项的尝试匹配次序是从左到右的,而且发现匹配项后就会忽略后面的选择项。因此正则/a|ab/匹配字符串”ab”时只会匹配到第一个字母a。
分组
将子表达式组合成一个独立单元,这就可以使用”|”、”*”等来对这个单元进行处理。例如/Java(script)?/可以用来匹配java或javascript,也就是script这个组合可以出现0-1次。
引用
()小括号除了可以将子表达式组合成一个独立单元,还能够定义子模式。当一个正则表达式成功地和目标字符串匹配时,可以从目标字符串中提取出和圆括号中的子模式相匹配的部分。后面会进行详细介绍。
引用
就是允许在同一个正则表达式的后部引用前面的子表达式。这是通过在字符””后加一个数字来实现的。这个数字制定了带圆括号的子表达式在正则表达式中的位置。这个位置是参与计数的左括号的位置
。例如/([Jj]ava([Ss]cript)?)siss(funw*)/正则中([Ss]cript)可以使用2来指代。对正则表达式中前一个子表达式的引用,并不是指对子表达式模式的引用,而是指与那个模式匹配的文本的引用。这样,引用可以用于实施一条约束,即一个字符串各个单独部分包含的是完全相同的字符。例如/‘”[‘”]/匹配位于单引号或双引号之间的0个或多个字符,但是它并不要求左侧和右侧的引号匹配,如果要匹配左右的引号类型,可以使用引用/([‘”])[w]1/。
如果不想生成带编码的引用
,可以使用”(?:)”进行组合,不记忆与改组相匹配的字符。
指定匹配位置
有一些正则表达式的元素匹配的是字符之间的位置,而不是实际字符。例如b匹配一个单词的边界。有时称这些元素为正则表达式的锚,因为它们将模式定位在目标字符串的特定位置上。最常见的锚元素是^,用来匹配字符串的开始,锚元素$用来匹配字符串的结尾。
任何正则表达式都可以作为锚点条件,如果在符号”(?=”和”)”之间加入一个表达式,它就是一个先行断言。用来说明圆括号内的表达式必须正确匹配。比如要匹配一个程序设计语言的名字,但只在其后有冒号时才匹配,可以使用/[jJ]ava([sS]cript)?(?=:)/。
带有”(?!”和”)”的断言是负向先行断言。用以指定接下来的字符都不匹配。例如/Java(?!Script)([A-Z]w*)/,用来匹配Java后面跟一个大写字母和任意个ASCII单词,但Java后面不能跟随”Script”。
修饰符
修饰符用来说明高级匹配模式的规则。JavaScript支持3个修饰符:i、g和m。
i:修饰符”i”用以说明模式匹配是不区分大小写的。
g:修饰符”g”用以说明模式匹配是全局的,也就是应该检索出字符串中的所有匹配。
m:修饰符”m”用以说明在多行模式中执行匹配。在这种模式下,如果待检索的字符串包含多行,那么^和锚字符除了匹配整个字符串的开始和结尾之外,还能够匹配每行的开始和结尾。比如/java/im可以匹配”Java”,也可以匹配”java\nis fun”。
String类型用于模式匹配的方法
JavaScript的String类型支持4种使用正则表达式的方法。
search():接收一个参数(字符串类型或者是正则对象),返回值是stringObject 中第一个与 regexp 相匹配的子串的起始位置。
replace():replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。该方法接收两个参数,第一个参数规定子字符串或要替换的模式的 RegExp 对象。第二个参数接收一个字符串值。规定了替换文本或生成替换文本的函数。如果正则表达式设置了修饰符g,那么源字符串中所有与模式匹配的子字符串都将被替换。但replace()的功能远不止单纯的替换,正则表达式中可以使用圆括号创建子表达式,正则表达式会记忆与每个子表达式匹配的文本。如果在替换字符串中出现了$加数字,那么replace()将与指定的子表达式相匹配的文本来替换。replace()的第二个参数可以接收一个函数来动态计算替换字符串。
match():match()方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。如果设置了修饰符g,则返回所有匹配结果。没有设置则只检索第一个匹配。即使不是全局搜索,也会返回一个数组,这种情况下,数组的第一个元素是匹配的字符串,余下的是子表达式对应的字符串。参数传入字符串相当于传入了一个非全局的正则表达式。
split():split() 方法用于把一个字符串分割成字符串数组。语法是stringObject.split(separator,howmany),separator可以是字符串或正则表达式,从该参数指定的地方分割 stringObject。howmany可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
RegExp对象
创建RegExp对象时接收两个参数:正则字符串和修饰符。
//注意"\"需要使用"\\"进行表示
var zipcode = new RegExp("\\d{5}", g);
RegExp的属性
每个RegExp对象都包含5个属性。
source:是一个只读字符串,包含正则表达式的文本。
global:用来说明这个正则表达式是否带有修饰符g
ignoreCase:用来说明正则表达式是否带有修饰符i
multiline:用来说明正则表达式是否带有修饰符m
lastIndex:这是一个可读写的整数。如果匹配模式带有g修饰符,这个属性存储整个字符串中下一次检索的开始位置,这个属性会被exec()和test()方法用到。
RegExp的方法
RegExp对象定义了两个用于执行模式匹配的操作方法。
exec():exec()接收一个字符串参数,方法的作用就是在参数字符串中执行匹配检索。如果它没有找到匹配就返回true。但如果它找到了匹配,它将返回一个数组,这个数组的第一个元素包含的是与正则表达式相匹配的字符串,余下的元素是与圆括号内的子表达式相匹配的子串。属性index包含了发生匹配的字符串位置,属性input引用的是正在执行检索的字符串。exec()总是返回一个匹配结果,并提供本次匹配的所有相关信息。当调用exec()的正则表达式对象具有g修饰符时,它将把正则表达式对象的lastIndex属性设置为紧挨着匹配子串的字符位置。当再次调用exec()时,它将从字符串的lastIndex位置开始向后进行检索。如果exec()没有查询到结果,它将把lastIndex设置为0.
test():test()的运行机制和exec()一致,只不过它只返回true和false
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。